/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package ejercicio.practica10;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 *
 * @author manolo
 */
public class RWMonitorAN {

    static int lectores = 0;
    static boolean escribiendo = false;
    private RandomAccessFile archivo;
    private final ReentrantLock bloqueo = new ReentrantLock();
    private final Condition listoEscribir = bloqueo.newCondition();
    private final Condition listoLectura = bloqueo.newCondition();
    File ruta;

    public RWMonitorAN(File ruta) {
        this.ruta = ruta;
    }

    void comienzaLectura() {
        bloqueo.lock();
        try {
            if (escribiendo) {
                try {
                    listoLectura.wait();
                    listoEscribir.wait();
                } catch (InterruptedException ex) {
                    System.out.println("Error: " + ex);

                }
            }

            lectores++;
            System.out.println("Lector inicia lectura...");
            RandomAccessFile archivo = null;
            try {
                archivo = new RandomAccessFile(ruta, "r");
            } catch (FileNotFoundException ex) {
                System.out.println("Error: " + ex);
            }
            try {
                archivo.seek(0);
                while (archivo.getFilePointer() < archivo.length()) {
                    System.out.println(archivo.readInt());
                }
                System.out.println();
            } catch (IOException ex) {
                System.out.println("Error: " + ex);
            }
        } finally {
            bloqueo.unlock();
        }
    }

    void finalizaLectura() {
        bloqueo.lock();
        try {
            lectores--;
            if (lectores == 0) {
                listoEscribir.signal();
            }
        } finally {
            System.out.println("Lector finaliza lectura...");
            bloqueo.unlock();
        }
    }

    void comienzaEscritura() {
        bloqueo.lock();
        try {
            if (escribiendo || lectores != 0) {
                try {
                    listoEscribir.wait();
                } catch (InterruptedException ex) {
                    System.out.println("Error: " + ex);
                }
            }

            escribiendo = true;

            System.out.println("Escritor inicia escritura...");
            try {
                try (RandomAccessFile archivo = new RandomAccessFile(ruta, "rw")) {
                    for (int i = 0; i < 5; i++) {
                        archivo.writeInt(i);
                    }
                }
                System.out.println("Fichero creado...");

            } catch (Exception ex) {
                System.out.println("Error: " + ex);
            }
        } finally {
            bloqueo.unlock();
        }
    }

    void finalizaEscritura() {
        bloqueo.lock();
        try {
            escribiendo = false;

            listoEscribir.signal();
            listoLectura.signal();
        } finally {
            System.out.println("Escritor finaliza escritura...");
            bloqueo.unlock();
        }

    }
}
